﻿using PagedList;
using PhoneStoreWeb.Models;
using System;
using System.Linq;
using System.Web.Mvc;

namespace PhoneStoreWeb.Controllers
{
    public class ProductController : Controller
    {
        PhoneStoreEntities storeDB = new PhoneStoreEntities();

        /// <summary>
        /// Render products
        /// </summary>
        /// <param name="page">current page number</param>
        /// <param name="pageSize">number of products per page</param>
        /// <param name="sorting">by Category, Manufacturer or Price</param>
        /// <param name="order">descending or ascending</param>
        /// <returns></returns>
        public ViewResult Index(int? page, int? size, string sorting, string order)
        {
            try
            {
                int pageNo = page ?? 1;
                int pageSize = size ?? 12;
                var products = (from product in storeDB.Products
                                where product.IsHidden == false
                                orderby product.Name
                                select product);
                if (sorting != null)
                {
                    if (sorting.Equals("Category"))
                    {
                        products.OrderBy(p => p.Category.Name);
                    }
                    else if (sorting.Equals("Manufacturer"))
                    {
                        products.OrderBy(p => p.Manufacturer.Name);
                    }
                    else if (sorting.Equals("Price"))
                    {
                        products.OrderBy(p => p.RetailPrice);
                    }
                }
                if (order != null)
                {
                    if (order.Equals("desc"))
                    {
                        products.Reverse();
                    }
                }
                // ~ <=> localhost:port
                var onePageOfProducts = products.ToPagedList(pageNo, pageSize);
                ViewBag.OnePageOfProducts = onePageOfProducts;
                return View();
            }
            catch (Exception ex)
            {
                Response.Write(ex.Message);
                return View();
            }
        }

        /// <summary>
        /// Render categories
        /// </summary>
        /// <returns></returns>
        [ChildActionOnly]
        public PartialViewResult CategoryMenu()
        {
            var categories = (from category in storeDB.Categories
                              orderby category.Name
                              select category);
            return PartialView(categories);
        }

        /// <summary>
        /// Render manufacturers 
        /// </summary>
        /// <returns></returns>
        [ChildActionOnly]
        public PartialViewResult ManufacturerMenu(string category)
        {
            ViewBag.Category = category;
            var manufacturers = (from manufacturer in storeDB.Manufacturers
                                 where (from product in storeDB.Products
                                        where product.Category.Name == category
                                        select product.ManufacturerID).Contains(manufacturer.ManufacturerID)
                                 orderby manufacturer.Name
                                 select manufacturer);
            return PartialView(manufacturers);
        }

        /// <summary>
        /// Render product details
        /// </summary>
        /// <param name="id">id of product</param>
        /// <returns></returns>
        [ChildActionOnly]
        public ViewResult Details(int? id)
        {
            // Lambda expression
            var productDetails = storeDB.Products.FirstOrDefault(p => p.ProductID == id);
            return View("Details", productDetails);
        }

        /// <summary>
        /// Get all products which belong to 'category' category
        /// </summary>
        /// <param name="category">category</param>
        /// <param name="page">current page number</param>
        /// <param name="pageSize">number of products per page</param>
        /// <param name="sorting">by Category, Manufacturer or Price</param>
        /// <param name="order">descending or ascending</param>
        /// <returns></returns>
        [ChildActionOnly]
        public ViewResult Product(string category, string manufacturer, int? page, int? size, string sorting, string order)
        {
            try
            {
                int pageNo = page ?? 1;
                int PageSize = size ?? 12;
                var products = String.IsNullOrEmpty(manufacturer) ? 
                                    (from product in storeDB.Products
                                     where product.IsHidden == false && product.Category.Name == category
                                     orderby product.Name
                                     select product) :
                                    (from product in storeDB.Products
                                     where product.IsHidden == false && product.Category.Name == category && product.Manufacturer.Name == manufacturer
                                     orderby product.Name
                                     select product);
                if (sorting != null)
                {
                    if (sorting.Equals("Category"))
                    {
                        products.OrderBy(p => p.Category.Name);
                    }
                    else if (sorting.Equals("Manufacturer"))
                    {
                        products.OrderBy(p => p.Manufacturer.Name);
                    }
                    else if (sorting.Equals("Price"))
                    {
                        products.OrderBy(p => p.RetailPrice);
                    }
                }
                if (order != null)
                {
                    if (order.Equals("desc"))
                    {
                        products.Reverse();
                    }
                }
                var onePageOfProducts = products.ToPagedList(pageNo, PageSize);
                ViewBag.OnePageOfProducts = onePageOfProducts;
                if (category.Equals("ĐIỆN THOẠI DI ĐỘNG"))
                {
                    return View("Smartphone");
                }
                else if (category.Equals("MÁY TÍNH BẢNG"))
                {
                    return View("Tablet");
                }
                else
                {
                    return View();
                }
            }
            catch (Exception ex)
            {
                Response.Write(ex.Message);
                return View();
            }
        }

        /// <summary>
        /// Take all products which belong to 'Smartphone'
        /// </summary>
        public ViewResult Smartphone(int? id, string manufacturer, int? page, int? size, string sorting, string order)
        {
            ViewBag.Category = "ĐIỆN THOẠI DI ĐỘNG";
            if (id == null)
            {
                return Product(ViewBag.Category, manufacturer, page, size, sorting, order);
            }
            else
            {
                return Details(id);
            }
        }

        /// <summary>
        /// Take all products which belong to 'Tablet'
        /// </summary>
        public ViewResult Tablet(int? id, string manufacturer, int? page, int? size, string sorting, string order)
        {
            ViewBag.Category = "MÁY TÍNH BẢNG";
            if (id == null)
            {
                return Product(ViewBag.Category, manufacturer, page, size, sorting, order);
            }
            else
            {
                return Details(id);
            }
        }
        
        public ViewResult Highlighted(int? page, int? size, string sorting, string order)
        {
            try
            {
                int pageNo = page ?? 1;
                int PageSize = size ?? 12;
                var products = (from product in storeDB.Products
                                where product.IsHidden == false && product.IsHighlighted == true
                                orderby product.Name
                                select product);
                if (sorting != null)
                {
                    if (sorting.Equals("Category"))
                    {
                        products.OrderBy(p => p.Category.Name);
                    }
                    else if (sorting.Equals("Manufacturer"))
                    {
                        products.OrderBy(p => p.Manufacturer.Name);
                    }
                    else if (sorting.Equals("Price"))
                    {
                        products.OrderBy(p => p.RetailPrice);
                    }
                }
                if (order != null)
                {
                    if (order.Equals("desc"))
                    {
                        products.Reverse();
                    }
                }
                var onePageOfProducts = products.ToPagedList(pageNo, PageSize);
                ViewBag.OnePageOfProducts = onePageOfProducts;
                return View("Index");
            }
            catch (Exception ex)
            {
                Response.Write(ex.Message);
                return View();
            }
        }

        public ViewResult New(int? page, int? size, string sorting, string order)
        {
            try
            {
                int pageNo = page ?? 1;
                int PageSize = size ?? 12;
                var products = (from product in storeDB.Products
                                where product.IsHidden == false && product.IsNew == true
                                orderby product.Name
                                select product);
                if (sorting != null)
                {
                    if (sorting.Equals("Category"))
                    {
                        products.OrderBy(p => p.Category.Name);
                    }
                    else if (sorting.Equals("Manufacturer"))
                    {
                        products.OrderBy(p => p.Manufacturer.Name);
                    }
                    else if (sorting.Equals("Price"))
                    {
                        products.OrderBy(p => p.RetailPrice);
                    }
                }
                if (order != null)
                {
                    if (order.Equals("desc"))
                    {
                        products.Reverse();
                    }
                }
                var onePageOfProducts = products.ToPagedList(pageNo, PageSize);
                ViewBag.OnePageOfProducts = onePageOfProducts;
                return View("Index");
            }
            catch (Exception ex)
            {
                Response.Write(ex.Message);
                return View();
            }
        }

        public ViewResult Selling(int? page, int? size, string sorting, string order)
        {
            try
            {
                int pageNo = page ?? 1;
                int PageSize = size ?? 12;
                var products = (from product in storeDB.Products
                                where product.IsHidden == false && product.IsSelling == true
                                orderby product.Name
                                select product);
                if (sorting != null)
                {
                    if (sorting.Equals("Category"))
                    {
                        products.OrderBy(p => p.Category.Name);
                    }
                    else if (sorting.Equals("Manufacturer"))
                    {
                        products.OrderBy(p => p.Manufacturer.Name);
                    }
                    else if (sorting.Equals("Price"))
                    {
                        products.OrderBy(p => p.RetailPrice);
                    }
                }
                if (order != null)
                {
                    if (order.Equals("desc"))
                    {
                        products.Reverse();
                    }
                }
                var onePageOfProducts = products.ToPagedList(pageNo, PageSize);
                ViewBag.OnePageOfProducts = onePageOfProducts;
                return View("Index");
            }
            catch (Exception ex)
            {
                Response.Write(ex.Message);
                return View();
            }
        }

        public ViewResult Promotion(int? page, int? size, string sorting, string order)
        {
            try
            {
                int pageNo = page ?? 1;
                int PageSize = size ?? 12;
                var products = (from product in storeDB.Products
                                where product.IsHidden == false && product.IsPromotional == true
                                orderby product.Name
                                select product);
                if (sorting != null)
                {
                    if (sorting.Equals("Category"))
                    {
                        products.OrderBy(p => p.Category.Name);
                    }
                    else if (sorting.Equals("Manufacturer"))
                    {
                        products.OrderBy(p => p.Manufacturer.Name);
                    }
                    else if (sorting.Equals("Price"))
                    {
                        products.OrderBy(p => p.RetailPrice);
                    }
                }
                if (order != null)
                {
                    if (order.Equals("desc"))
                    {
                        products.Reverse();
                    }
                }
                var onePageOfProducts = products.ToPagedList(pageNo, PageSize);
                ViewBag.OnePageOfProducts = onePageOfProducts;
                return View("Index");
            }
            catch (Exception ex)
            {
                Response.Write(ex.Message);
                return View();
            }
        }

        /// <summary>
        /// Take all products which belong to 'id' manufacturer
        /// </summary>
        /// <param name="id">manufacturer name</param>
        /// /// <param name="category">category name</param>
        /// <returns></returns>
        public ViewResult Manufacturer(string category, string id, int? page, int? size, string sorting, string order)
        {
            if (category.Equals("Smartphone"))
            {
                return Smartphone(null, id, page, size, sorting, order);
            }
            else if (category.Equals("Tablet"))
            {
                return Tablet(null, id, page, size, sorting, order);
            }
            return View();
        }
    }
}